{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "restricted_boltzmann_machines.ipynb",
      "provenance": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "id": "uCQrVzZSoFi-"
      },
      "outputs": [],
      "source": [
        "import tensorflow as tf\n",
        "import numpy as np\n",
        "import matplotlib.pyplot as plt"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "(train_data, _), (test_data, _) =  tf.keras.datasets.mnist.load_data()\n",
        "train_data = train_data/np.float32(255)\n",
        "train_data = np.reshape(train_data, (train_data.shape[0], 784))\n",
        "\n",
        "\n",
        "test_data = test_data/np.float32(255)\n",
        "test_data = np.reshape(test_data, (test_data.shape[0], 784))"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "9os9_HheZzr_",
        "outputId": "8ba0b424-eebc-4c33-96c6-ab3de4064e5c"
      },
      "execution_count": 3,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz\n",
            "11493376/11490434 [==============================] - 0s 0us/step\n",
            "11501568/11490434 [==============================] - 0s 0us/step\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "#Class that defines the behavior of the RBM\n",
        "class RBM(object):\n",
        "    \n",
        "    def __init__(self, input_size, output_size, lr=1.0, batchsize=100):\n",
        "        \"\"\"\n",
        "        m: Number of neurons in visible layer\n",
        "        n: number of neurons in hidden layer\n",
        "        \"\"\"\n",
        "        #Defining the hyperparameters\n",
        "        self._input_size = input_size #Size of Visible\n",
        "        self._output_size = output_size #Size of outp\n",
        "        self.learning_rate = lr #The step used in gradient descent\n",
        "        self.batchsize = batchsize #The size of how much data will be used for training per sub iteration\n",
        "        \n",
        "        #Initializing weights and biases as matrices full of zeroes\n",
        "        self.w = tf.zeros([input_size, output_size], np.float32) #Creates and initializes the weights with 0\n",
        "        self.hb = tf.zeros([output_size], np.float32) #Creates and initializes the hidden biases with 0\n",
        "        self.vb = tf.zeros([input_size], np.float32) #Creates and initializes the visible biases with 0\n",
        "\n",
        "\n",
        "    #Forward Pass\n",
        "    def prob_h_given_v(self, visible, w, hb):\n",
        "        #Sigmoid \n",
        "        return tf.nn.sigmoid(tf.matmul(visible, w) + hb)\n",
        "\n",
        "    #Backward Pass\n",
        "    def prob_v_given_h(self, hidden, w, vb):\n",
        "        return tf.nn.sigmoid(tf.matmul(hidden, tf.transpose(w)) + vb)\n",
        "    \n",
        "    #Generate the sample probability\n",
        "    def sample_prob(self, probs):\n",
        "        return tf.nn.relu(tf.sign(probs - tf.random.uniform(tf.shape(probs))))\n",
        "\n",
        "    #Training method for the model\n",
        "    def train(self, X, epochs=10):\n",
        "               \n",
        "        loss = []\n",
        "        for epoch in range(epochs):\n",
        "            #For each step/batch\n",
        "            for start, end in zip(range(0, len(X), self.batchsize),range(self.batchsize,len(X), self.batchsize)):\n",
        "                batch = X[start:end]\n",
        "                    \n",
        "                #Initialize with sample probabilities\n",
        "                    \n",
        "                h0 = self.sample_prob(self.prob_h_given_v(batch, self.w, self.hb))\n",
        "                v1 = self.sample_prob(self.prob_v_given_h(h0, self.w, self.vb))\n",
        "                h1 = self.prob_h_given_v(v1, self.w, self.hb)\n",
        "                    \n",
        "                #Create the Gradients\n",
        "                positive_grad = tf.matmul(tf.transpose(batch), h0)\n",
        "                negative_grad = tf.matmul(tf.transpose(v1), h1)\n",
        "                    \n",
        "                #Update learning rates \n",
        "                self.w = self.w + self.learning_rate *(positive_grad - negative_grad) / tf.dtypes.cast(tf.shape(batch)[0],tf.float32)\n",
        "                self.vb = self.vb +  self.learning_rate * tf.reduce_mean(batch - v1, 0)\n",
        "                self.hb = self.hb +  self.learning_rate * tf.reduce_mean(h0 - h1, 0)\n",
        "                    \n",
        "            #Find the error rate\n",
        "            err = tf.reduce_mean(tf.square(batch - v1))\n",
        "            print ('Epoch: %d' % epoch,'reconstruction error: %f' % err)\n",
        "            loss.append(err)\n",
        "                    \n",
        "        return loss\n",
        "        \n",
        "    #Create expected output for our DBN\n",
        "    def rbm_output(self, X):\n",
        "        out = tf.nn.sigmoid(tf.matmul(X, self.w) + self.hb)\n",
        "        return out\n",
        "    \n",
        "    def rbm_reconstruct(self,X):\n",
        "        h = tf.nn.sigmoid(tf.matmul(X, self.w) + self.hb)\n",
        "        reconstruct = tf.nn.sigmoid(tf.matmul(h, tf.transpose(self.w)) + self.vb)\n",
        "        return reconstruct\n",
        "            "
      ],
      "metadata": {
        "id": "y9ALhkKMaKKW"
      },
      "execution_count": 4,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "#Size of inputs is the number of inputs in the training set\n",
        "input_size = train_data.shape[1]\n",
        "rbm = RBM(input_size, 200)\n",
        "\n",
        "err = rbm.train(train_data,50)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "76gVBUaSaUgz",
        "outputId": "3f387a06-4357-4363-9ef8-11e83bd58173"
      },
      "execution_count": 5,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Epoch: 0 reconstruction error: 0.059060\n",
            "Epoch: 1 reconstruction error: 0.053532\n",
            "Epoch: 2 reconstruction error: 0.051043\n",
            "Epoch: 3 reconstruction error: 0.049189\n",
            "Epoch: 4 reconstruction error: 0.046627\n",
            "Epoch: 5 reconstruction error: 0.047418\n",
            "Epoch: 6 reconstruction error: 0.046459\n",
            "Epoch: 7 reconstruction error: 0.046383\n",
            "Epoch: 8 reconstruction error: 0.043315\n",
            "Epoch: 9 reconstruction error: 0.043287\n",
            "Epoch: 10 reconstruction error: 0.043188\n",
            "Epoch: 11 reconstruction error: 0.044013\n",
            "Epoch: 12 reconstruction error: 0.043122\n",
            "Epoch: 13 reconstruction error: 0.043767\n",
            "Epoch: 14 reconstruction error: 0.043482\n",
            "Epoch: 15 reconstruction error: 0.042345\n",
            "Epoch: 16 reconstruction error: 0.041807\n",
            "Epoch: 17 reconstruction error: 0.041877\n",
            "Epoch: 18 reconstruction error: 0.041188\n",
            "Epoch: 19 reconstruction error: 0.041940\n",
            "Epoch: 20 reconstruction error: 0.041854\n",
            "Epoch: 21 reconstruction error: 0.042090\n",
            "Epoch: 22 reconstruction error: 0.041938\n",
            "Epoch: 23 reconstruction error: 0.041483\n",
            "Epoch: 24 reconstruction error: 0.041424\n",
            "Epoch: 25 reconstruction error: 0.040641\n",
            "Epoch: 26 reconstruction error: 0.040626\n",
            "Epoch: 27 reconstruction error: 0.042108\n",
            "Epoch: 28 reconstruction error: 0.041044\n",
            "Epoch: 29 reconstruction error: 0.040565\n",
            "Epoch: 30 reconstruction error: 0.041008\n",
            "Epoch: 31 reconstruction error: 0.041025\n",
            "Epoch: 32 reconstruction error: 0.039852\n",
            "Epoch: 33 reconstruction error: 0.040936\n",
            "Epoch: 34 reconstruction error: 0.040475\n",
            "Epoch: 35 reconstruction error: 0.040527\n",
            "Epoch: 36 reconstruction error: 0.040601\n",
            "Epoch: 37 reconstruction error: 0.041524\n",
            "Epoch: 38 reconstruction error: 0.040796\n",
            "Epoch: 39 reconstruction error: 0.039891\n",
            "Epoch: 40 reconstruction error: 0.040564\n",
            "Epoch: 41 reconstruction error: 0.041044\n",
            "Epoch: 42 reconstruction error: 0.042090\n",
            "Epoch: 43 reconstruction error: 0.039622\n",
            "Epoch: 44 reconstruction error: 0.040299\n",
            "Epoch: 45 reconstruction error: 0.039993\n",
            "Epoch: 46 reconstruction error: 0.040313\n",
            "Epoch: 47 reconstruction error: 0.039615\n",
            "Epoch: 48 reconstruction error: 0.039495\n",
            "Epoch: 49 reconstruction error: 0.040075\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "plt.plot(err)\n",
        "plt.xlabel('epochs')\n",
        "plt.ylabel('cost')"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 301
        },
        "id": "AQa3aNTjaUJk",
        "outputId": "cccc9eb3-6d5a-4d4a-f050-ee473ea287e5"
      },
      "execution_count": 7,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "Text(0, 0.5, 'cost')"
            ]
          },
          "metadata": {},
          "execution_count": 7
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "\n",
        "\n",
        "out = rbm.rbm_reconstruct(test_data)\n",
        "\n",
        "# Plotting original and reconstructed images\n",
        "row, col = 2, 8\n",
        "idx = np.random.randint(0, 100, row * col // 2)\n",
        "f, axarr = plt.subplots(row, col, sharex=True, sharey=True, figsize=(20,4))\n",
        "for fig, row in zip([test_data,out], axarr):\n",
        "    for i,ax in zip(idx,row):\n",
        "        ax.imshow(tf.reshape(fig[i],[28, 28]), cmap='Greys_r')\n",
        "        ax.get_xaxis().set_visible(False)\n",
        "        ax.get_yaxis().set_visible(False)\n",
        "\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 239
        },
        "id": "fzDte7X1ab4p",
        "outputId": "1bb52bb4-7504-460a-c542-0ceab5a946b3"
      },
      "execution_count": 6,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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LPHWrVtNrkePHhK/8847Jsc1CMnw81itWrXMuFevXhI3aNDA5PSct2TJEpP77bffJN5zzz1N7pdfftnhewBAUcCKFgAAAAAAgIjwoAUAAAAAACAiPGgBAAAAAACISF7t0aJbzbVo0cLk+vXrJ7GuYw7BtvT1LXxXrVplxu3atZPY16eee+65En/99dcmp9vXvf322zv+D0BW6PNm4cKFJqdrh8uWLWtyem8Xz59/PXv2lNi3L/z4448lpgYZyE9+PnjsscckbtWqlcnp69HEiRNNbs2aNZEfW8mSJc14v/32k9jvibBs2TKJN27cGPmxYOf0uVSlShWT23fffSU+4YQTTG6vvfaS2O/Rovd20decEELYtGmTGXMdwo74PVr0fW0IIZxxxhlx/1bfE1944YUmt2LFCon1niwhcC4CRZ1vE1+xYkWJ/b6ZX331lRnXq1dPYn8d0/c9hxxyiMmddtppEj/99NMmt3btWoknT55scv66GgVWtAAAAAAAAESEBy0AAAAAAAARyenSIb+MUS+jfeCBB0zusMMOk9gvh54zZ47E33//vcmVL1/ejBcsWCCxXoobQgj169eXuFGjRibXvn17iXU5SgghTJs2TWKWSWbe9u3bJd6yZYvJ6TaYvvV3nTp1JPZlA2XKlDHja6+9VuK2bdua3EUXXSSxL11C6nRJYAjJtzCl1SmSpa9BvjyndevWEuulsCGE8Ouvv0rs55Wo6FJHX8r4z3/+U+KxY8ea3ODBgyX286G/diE99DVp27ZtJrd69WqJ/TJmPXftscceJnfeeedJPGzYMJOjRAzx6HubE0880eSuuOIKM9bz4eeff25yDz74oMTffvutyTGvpIf/jaQVld8a+r/R//fq/8ai8t+br3x50AEHHCBxx44dTU5fq8qVK2dyuuw5hBA2b94s8bp160xO33fpstoQQli5cqXEjzzyiMkNGDBA4u+++87k9POCqLCiBQAAAAAAICI8aAEAAAAAAIgID1oAAAAAAAAiktN7tPga5L59+0qs92TxPvvsMzPWrTY/+OADk9O10iGEcOihh0q8ePFik9P7cPiWjN27d5fYt5maPXu2xLqtFDJD127+8MMPJnfXXXdJrGsBQ7Btwn39of+O//GPf0h8+OGHm1zv3r0l/stf/mJy6WglVlyccsopZvzoo49K7P+d6fpNvy+Trid/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\n",
            "text/plain": [
              "<Figure size 1440x288 with 16 Axes>"
            ]
          },
          "metadata": {
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        ""
      ],
      "metadata": {
        "id": "0-G_oy5TadA9"
      },
      "execution_count": null,
      "outputs": []
    }
  ]
}